// UserInteractionManager.cpp
//
#include "UserInteractionManager.h"

#include <QKeySequence>
#include <QShortcut>

#include <iostream>


#include "Utils/StringTools.h"
#include "Utils/MemCheck.h"
using namespace QtFwk;

// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
std::map<std::string,unsigned int> UserInteractionManager::mouseCommandCodes;
std::map<std::string,unsigned int> UserInteractionManager::keyboardCommandCodes;
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------

// ------------------------------------------------------------------------------------------------
unsigned int UserInteractionManager::decodeMouseCommnand( const std::string &command )
{
	if( mouseCommandCodes.empty() )
	{
		mouseCommandCodes.insert( std::make_pair("Alt",         MouseStatus::ModifierAlt) );
		mouseCommandCodes.insert( std::make_pair("Ctrl",        MouseStatus::ModifierCtrl) );
		mouseCommandCodes.insert( std::make_pair("Shift",       MouseStatus::ModifierShift) );
		mouseCommandCodes.insert( std::make_pair("LeftButton",  MouseStatus::ButtonLeft) );
		mouseCommandCodes.insert( std::make_pair("RightButton", MouseStatus::ButtonRight) );
		mouseCommandCodes.insert( std::make_pair("MidButton",   MouseStatus::ButtonMiddle) );
		mouseCommandCodes.insert( std::make_pair("DoubleClick", MouseStatus::DoubleClick) );
		mouseCommandCodes.insert( std::make_pair("Moving",      MouseStatus::Moving) );
		mouseCommandCodes.insert( std::make_pair("Drag",        MouseStatus::Drag) );
		mouseCommandCodes.insert( std::make_pair("Wheel",       MouseStatus::Wheel) );
	}

	unsigned int commandCode = 0;
	std::vector<std::string> v= split(command,"+");
	for( size_t i=0; i<v.size(); ++i )
	{
		// find the command
		std::map<std::string,unsigned int>::iterator it = mouseCommandCodes.find(v[i]);
		if( it != mouseCommandCodes.end() )
			commandCode |= it->second;
	}
	
	return commandCode;	
}


// ------------------------------------------------------------------------------------------------
unsigned int UserInteractionManager::decodeKeyboardCommnand( const std::string &command )
{
	QKeySequence ks( QString(command.c_str() ));

	//std::cout << ks.toString().toStdString() << std::endl;

	unsigned int commandCode = (int)ks;

	keyboardCommandCodes.insert( std::make_pair(command, (int)ks) );

#if 0
	if( keyboardCommandCodes.empty() )
	{
		ks.
		for( int c=0; c<256; ++c )
			keyboardCommandCodes.insert( std::make_pair(std::string("").append(1,(unsigned char)c), c) );

		mouseCommandCodes.insert( std::make_pair("Alt",         KeyboardStatus::ModifierAlt) );
		mouseCommandCodes.insert( std::make_pair("Ctrl",        KeyboardStatus::ModifierCtrl) );
		mouseCommandCodes.insert( std::make_pair("Shift",       KeyboardStatus::ModifierShift) );

		mouseCommandCodes.insert( std::make_pair("Enter",       KeyboardStatus::ModifierShift) );
		mouseCommandCodes.insert( std::make_pair("Space",       KeyboardStatus::ModifierShift) );
		mouseCommandCodes.insert( std::make_pair("Tab",         KeyboardStatus::ModifierShift) );
		mouseCommandCodes.insert( std::make_pair("Backspace",   KeyboardStatus::ModifierShift) );


		// @todo: add modifiers, f1..f12, spacing, arrows

	}

	unsigned int commandCode = 0;
	std::vector<std::string> v = split(command,"+");
	for( size_t i=0; i<v.size(); ++i )
	{
		// find the command
		std::map<std::string,unsigned int>::iterator it = keyboardCommandCodes.find(v[i]);
		if( it != keyboardCommandCodes.end() )
			commandCode |= it->second;
	}

#endif
	return commandCode;	
}


#if 0

#include <QMap>
#include <QAction>
#include <QMouseEvent>
#include <QWheelEvent>

#include "Utils/MemCheck.h"

using namespace QtFwk;

// ------------------------------------------------------------------------------------------------
UserInteractionManager::UserInteractionManager(){ clear(); }

// ------------------------------------------------------------------------------------------------
UserInteractionManager::~UserInteractionManager(){ clear(); }

// ------------------------------------------------------------------------------------------------
void UserInteractionManager::clear()
{
	keyBindings.clear();
	mouseBindings.clear();
}

// ------------------------------------------------------------------------------------------------
void UserInteractionManager::addKeyBinding(const QString &name, const QString &text, const QString &shortcut, QObject *receiver, const char *method )
{
	QAction *a = new QAction(receiver);
	a->setText(text);
	a->setShortcutContext(Qt::WidgetShortcut);
	a->setShortcut( QKeySequence(shortcut) );

	connect(a, SIGNAL(triggered()), receiver, method);

	keyBindings.insert(name,a);
}

// ------------------------------------------------------------------------------------------------
QAction* UserInteractionManager::getAction(const QString &name)
{
	if( !keyBindings.contains( name ) )
		return NULL;

	return keyBindings[name];
}

// ------------------------------------------------------------------------------------------------
QList<QAction*> UserInteractionManager::getKeyBindings()
{
	return keyBindings.values();
}

// ------------------------------------------------------------------------------------------------
void UserInteractionManager::addMouseBinding(const QString &name, const QString &shortcut )
{
	const int plus = shortcut.lastIndexOf("+") + 1;
	
	QString mouseButton = shortcut.mid(plus);

	//QString accel = "";
	//if( plus > 1 )	 accel = shortcut.left(plus);

	//QKeySequence ks(accel);
	//QString k = (ks.toString() + mouseButton).toLower();

	QAction *a = new QAction(this);
	a->setText(name);
	a->setShortcutContext(Qt::WidgetShortcut);
	a->setShortcut( QKeySequence(shortcut) );

	//connect(a, SIGNAL(triggered()), receiver, method);

	mouseBindings.insert(shortcut, a);
}

// ------------------------------------------------------------------------------------------------
//template< typename T >
//void UserInteractionManager::addMouseBinding(const QString &name, const QString &shortcut, T *obj, void (T::*m)() )
//{
//	obj->*m();
//}

// ------------------------------------------------------------------------------------------------
//QString UserInteractionManager::getMouseAction( QGraphicsSceneWheelEvent *e)
//{
//	QKeySequence ks( e->modifiers() );
//
//	QString k = (ks.toString() + "Wheel").toLower();
//
//	QString actionName = "";
//
//	Binding::Iterator it =  mouseBindings.find( k );
//	if( it != mouseBindings.end() )
//		actionName = *it;
//
//	return actionName;
//}

// ------------------------------------------------------------------------------------------------
//QString UserInteractionManager::getMouseAction( QWheelEvent *e)
//{
//	QKeySequence ks( e->modifiers() );
//
//	QString k = (ks.toString() + "Wheel").toLower();
//
//	QString actionName = "";
//
//	Binding::iterator it =  mouseBindings.find( k );
//	if( it != mouseBindings.end() )
//		actionName = *it;
//
//	return actionName;
//}

// ------------------------------------------------------------------------------------------------
//QString UserInteractionManager::getMouseAction( QGraphicsSceneMouseEvent *e)
//{
//	QKeySequence ks( e->modifiers() );
//
//	QString k = "";
//	
//	switch( e->button() )
//	{
//	case Qt::MidButton:		k = (ks.toString() + "MidButton").toLower();	break;
//	case Qt::LeftButton:	k = (ks.toString() + "LeftButton").toLower();	break;
//	case Qt::RightButton:	k = (ks.toString() + "RightButton").toLower();	break;
//	}
//
//	
//	QString actionName = "";
//
//	Binding::iterator it =  mouseBindings.find(k);
//	if( it != mouseBindings.end() )
//		actionName = *it;
//
//	return actionName;
//}

// ------------------------------------------------------------------------------------------------
//QString UserInteractionManager::getMouseAction( QMouseEvent *e)
//{
//	QKeySequence ks( e->modifiers() );
//
//	QString k = "";
//	
//	switch( e->button() )
//	{
//	case Qt::MidButton:		k = (ks.toString() + "MidButton").toLower();	break;
//	case Qt::LeftButton:	k = (ks.toString() + "LeftButton").toLower();	break;
//	case Qt::RightButton:	k = (ks.toString() + "RightButton").toLower();	break;
//	}
//
//	
//	QString actionName = "";
//
//	Binding::iterator it =  mouseBindings.find(k);
//	if( it != mouseBindings.end() )
//		actionName = *it;
//
//	return actionName;
//}

// ------------------------------------------------------------------------------------------------
//bool UserInteractionManager::isBound( const MouseStatus &ms )
//{
//	if( mouseBindings.find( ms.toString() ) == mouseBindings.end() )
//		return false;
//	return true;
//}
#endif